﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace _0912089
{
    public class MoveAction : ActionHelper
    {
        private float _beginSpeed;
        private float _acceleration;
        private float _currentSpeed;

        public override View View
        {
            get { return base.View; }
            set
            {
                base.View = value;

                BeginPosition = value.Position;
                _currentPosition = value.Position;
            }
        }

        public MoveAction(string actionName, View view, Vector2 endPos, float beginSpeed, float acceleration)
            : base(actionName)
        {
            _actionName = actionName;

            initAction(view, endPos, beginSpeed, acceleration);
        }

        public MoveAction(View view, Vector2 endPos, float beginSpeed, float acceleration)
        {
            initAction(view, endPos, beginSpeed, acceleration);
        }

        private void initAction(View view, Vector2 endPos, float beginSpeed, float acceleration)
        {
            if (view != null)
            {
                BeginPosition = view.Position;
                _currentPosition = view.Position;
                View = view;
            }
            _endPosition = endPos;
            _beginSpeed = beginSpeed;
            _currentSpeed = beginSpeed;
            _acceleration = acceleration;
        }

        public override void reverse()
        {
            base.reverse();
            Vector2 temp = _endPosition;
            _endPosition = _beginPosition;
            _beginPosition = temp;

            _currentSpeed = _beginSpeed;
        }

        public override void excuteAction(GameTime gameTime)
        {
            if (View.Position == _endPosition)
            {
                _isActioning = false;
                postNotification(ActionName, "Done");
            }

            _currentTotalTime += gameTime.ElapsedGameTime.Milliseconds;
            float second = _currentTotalTime / 1000;

            // v = v0 + a * t
            float deltaVelocity = _acceleration * second;
            _currentSpeed += deltaVelocity;
            View.Position = calculateNewPosition(View.Position, _endPosition, _currentSpeed);

            _currentPosition = View.Position;
        }

        private Vector2 calculateNewPosition(Vector2 pos, Vector2 targetPos, float speed)
        {
            // A(Position)-------C--------------B(TargetPosition)
            double AB = Math.Sqrt((pos.X - targetPos.X) * (pos.X - targetPos.X) + (pos.Y - targetPos.Y) * (pos.Y - targetPos.Y));
            double AC = speed;
            if (AB < AC)
            {
                return targetPos;
            }
            double k = AC / AB;
            Vector2 vectorAB = targetPos - pos;
            Vector2 X = new Vector2(vectorAB.X * (float)k, vectorAB.Y * (float)k);
            Vector2 C = new Vector2(pos.X + X.X, pos.Y + X.Y);

            return C;
        }
    }
}
